#ifndef BIGQ_H
#define BIGQ_H

#include <pthread.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include "Pipe.h"
#include "File.h"


using namespace std;

 /**
  *Class to help map a record to a run
  */
class RunRecord{
    public:
        int run;
        Record * record;
        RunRecord(Record* record, int run);
};

/**
 *Struct to help sort records
 */
struct RecordComparator {
    public:
        ComparisonEngine engine;
        OrderMaker order;
        //bool direction;

        RecordComparator(){}

        bool operator() (Record * a, Record * b){
            int result = engine.Compare(a, b, &order);

            if(result<0)
                return true;
            return false;
        }

        bool operator() (RunRecord * a, RunRecord * b){
            int result = engine.Compare(a->record, b->record, &order);

            if(result<0)
                return false;
            return true;
        }
};

typedef priority_queue<RunRecord,vector<RunRecord*>, RecordComparator> pq_type;

class BigQ {
    private:
        char tempPath[200];

    public:
        OrderMaker& sortorder;
        Pipe& in;
        Pipe& out;

        File file;
        Page page;

        pthread_t thread;

        struct RecordComparator comparator;

        vector<Record*> records;

        int noOfRuns;
        int currentPage;
        int runlen;
        int noOfPages;

        /**
         *constructors
         */
        BigQ (Pipe &in, Pipe &out, OrderMaker &sortorder, int runlen);
        ~BigQ ();

        /**
         *Sort recored in in pipe and put in out pipe
         */
        void Sort();

        /**
         *Write a run of sorted records to a file
         */
        void RunToFile();

        void Wait();
};

/**
 *Function that the BigQ thread will run
 */
void *Worker(void* param);

#endif
